home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 60 / IOPROG_60.ISO / soft / c++ / gsl-1.1.1-setup.exe / {app} / src / integration / qawc.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-08-22  |  5.3 KB  |  221 lines

  1. /* integration/qawc.c
  2.  * 
  3.  * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough
  4.  * 
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or (at
  8.  * your option) any later version.
  9.  * 
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #include <config.h>
  21. #include <math.h>
  22. #include <float.h>
  23. #include <gsl/gsl_math.h>
  24. #include <gsl/gsl_errno.h>
  25. #include <gsl/gsl_integration.h>
  26.  
  27. #include "initialise.c"
  28. #include "set_initial.c"
  29. #include "qpsrt.c"
  30. #include "util.c"
  31. #include "qc25c.c"
  32.  
  33. int
  34. gsl_integration_qawc (gsl_function * f,
  35.               const double a, const double b, const double c,
  36.               const double epsabs, const double epsrel,
  37.               const size_t limit,
  38.               gsl_integration_workspace * workspace,
  39.               double *result, double *abserr)
  40. {
  41.   double area, errsum;
  42.   double result0, abserr0;
  43.   double tolerance;
  44.   size_t iteration = 0;
  45.   int roundoff_type1 = 0, roundoff_type2 = 0, error_type = 0;
  46.   int err_reliable;
  47.   int sign = 1;
  48.   double lower, higher;
  49.  
  50.   /* Initialize results */
  51.  
  52.   *result = 0;
  53.   *abserr = 0;
  54.  
  55.   if (limit > workspace->limit)
  56.     {
  57.       GSL_ERROR ("iteration limit exceeds available workspace", GSL_EINVAL) ;
  58.     }
  59.  
  60.   if (b < a) 
  61.     {
  62.       lower = b ;
  63.       higher = a ;
  64.       sign = -1 ;
  65.     }
  66.   else
  67.     {
  68.       lower = a;
  69.       higher = b;
  70.     }
  71.  
  72.   initialise (workspace, lower, higher);
  73.  
  74.   if (epsabs <= 0 && (epsrel < 50 * GSL_DBL_EPSILON || epsrel < 0.5e-28))
  75.     {
  76.       GSL_ERROR ("tolerance cannot be acheived with given epsabs and epsrel",
  77.          GSL_EBADTOL);
  78.     }
  79.  
  80.   if (c == a || c == b) 
  81.     {
  82.       GSL_ERROR ("cannot integrate with singularity on endpoint", GSL_EINVAL);
  83.     }      
  84.  
  85.   /* perform the first integration */
  86.  
  87.   qc25c (f, lower, higher, c, &result0, &abserr0, &err_reliable);
  88.  
  89.   set_initial_result (workspace, result0, abserr0);
  90.  
  91.   /* Test on accuracy, use 0.01 relative error as an extra safety
  92.      margin on the first iteration (ignored for subsequent iterations) */
  93.  
  94.   tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (result0));
  95.  
  96.   if (abserr0 < tolerance && abserr0 < 0.01 * fabs(result0)) 
  97.     {
  98.       *result = sign * result0;
  99.       *abserr = abserr0;
  100.  
  101.       return GSL_SUCCESS;
  102.     }
  103.   else if (limit == 1)
  104.     {
  105.       *result = sign * result0;
  106.       *abserr = abserr0;
  107.  
  108.       GSL_ERROR ("a maximum of one iteration was insufficient", GSL_EMAXITER);
  109.     }
  110.  
  111.   area = result0;
  112.   errsum = abserr0;
  113.  
  114.   iteration = 1;
  115.  
  116.   do
  117.     {
  118.       double a1, b1, a2, b2;
  119.       double a_i, b_i, r_i, e_i;
  120.       double area1 = 0, area2 = 0, area12 = 0;
  121.       double error1 = 0, error2 = 0, error12 = 0;
  122.       int err_reliable1, err_reliable2;
  123.  
  124.       /* Bisect the subinterval with the largest error estimate */
  125.  
  126.       retrieve (workspace, &a_i, &b_i, &r_i, &e_i);
  127.  
  128.       a1 = a_i; 
  129.       b1 = 0.5 * (a_i + b_i);
  130.       a2 = b1;
  131.       b2 = b_i;
  132.  
  133.       if (c > a1 && c < b1) 
  134.     {
  135.       b1 = 0.5 * (c + b2) ;
  136.       a2 = b1;
  137.     }
  138.       else if (c > b1 && c < b2)
  139.     {
  140.       b1 = 0.5 * (a1 + c) ;
  141.       a2 = b1;
  142.     }
  143.  
  144.       qc25c (f, a1, b1, c, &area1, &error1, &err_reliable1);
  145.       qc25c (f, a2, b2, c, &area2, &error2, &err_reliable2);
  146.  
  147.       area12 = area1 + area2;
  148.       error12 = error1 + error2;
  149.  
  150.       errsum += (error12 - e_i);
  151.       area += area12 - r_i;
  152.  
  153.       if (err_reliable1 && err_reliable2)
  154.     {
  155.       double delta = r_i - area12;
  156.  
  157.       if (fabs (delta) <= 1.0e-5 * fabs (area12) && error12 >= 0.99 * e_i)
  158.         {
  159.           roundoff_type1++;
  160.         }
  161.       if (iteration >= 10 && error12 > e_i)
  162.         {
  163.           roundoff_type2++;
  164.         }
  165.     }
  166.  
  167.       tolerance = GSL_MAX_DBL (epsabs, epsrel * fabs (area));
  168.  
  169.       if (errsum > tolerance)
  170.     {
  171.       if (roundoff_type1 >= 6 || roundoff_type2 >= 20)
  172.         {
  173.           error_type = 2;    /* round off error */
  174.         }
  175.  
  176.       /* set error flag in the case of bad integrand behaviour at
  177.          a point of the integration range */
  178.  
  179.       if (subinterval_too_small (a1, a2, b2))
  180.         {
  181.           error_type = 3;
  182.         }
  183.     }
  184.  
  185.       update (workspace, a1, b1, area1, error1, a2, b2, area2, error2);
  186.  
  187.       retrieve (workspace, &a_i, &b_i, &r_i, &e_i);
  188.  
  189.       iteration++;
  190.  
  191.     }
  192.   while (iteration < limit && !error_type && errsum > tolerance);
  193.  
  194.   *result = sign * sum_results (workspace);
  195.   *abserr = errsum;
  196.  
  197.   if (errsum <= tolerance)
  198.     {
  199.       return GSL_SUCCESS;
  200.     }
  201.   else if (error_type == 2)
  202.     {
  203.       GSL_ERROR ("roundoff error prevents tolerance from being achieved",
  204.          GSL_EROUND);
  205.     }
  206.   else if (error_type == 3)
  207.     {
  208.       GSL_ERROR ("bad integrand behavior found in the integration interval",
  209.          GSL_ESING);
  210.     }
  211.   else if (iteration == limit)
  212.     {
  213.       GSL_ERROR ("maximum number of subdivisions reached", GSL_EMAXITER);
  214.     }
  215.   else
  216.     {
  217.       GSL_ERROR ("could not integrate function", GSL_EFAILED);
  218.     }
  219.  
  220. }
  221.